import WebSocket, { MessageEvent } from "ws";
import { BrowserWindow } from "electron";
import { ICreateWs } from "../types/ws.ts";
import { CallStatus, ChatType, IMessage, MessageStatus, MessageType } from "../types/message.ts";
import { getTargetWindow } from "../window/CreateWindow.ts";
import { InsertMessages } from "../db/servers/message";
import { UpdateOrCreateSession } from "../db/servers/session";
import { buildSession } from "../utils/common.ts";

const reconnectCountMax = 5;
const reconnectInterval = 2000;
const heartInterval = 100000;
const wsUrl = import.meta.env.VITE_API_WS_URL;
let ws: WebSocket | null = null;
let reconnectCount = 0;
let lockReconnect = false;
let heartTimer: NodeJS.Timeout | null = null;
let reconnectTimer: NodeJS.Timeout | null = null;
let wsUserParams: ICreateWs | null = null;

// 建立 WebSocket 连接
function createWs(params: ICreateWs) {
  wsUserParams = params;
  if (ws) {
    cleanupWebSocket();
    closeWs();
  }
  try {
    ws = new WebSocket(wsUrl, {
      headers: {
        "x-token": wsUserParams.token,
      },
    });
    ws.addEventListener("open", onOpen);
    ws.addEventListener("message", onMessage);
    ws.addEventListener("close", onClose);
    ws.addEventListener("error", onError);
  } catch (err) {
    console.error("❌ WebSocket 创建失败:", err);
    reconnect();
  }
}

// WebSocket 连接成功
async function onOpen() {
  resetState();
  await startHeartBeat();
  console.log("✅ WebSocket 连接成功 🎉");
}

// 接收消息
async function onMessage(event: MessageEvent) {
  try {
    const message: IMessage = JSON.parse(event.data as string);
    console.log("📩 接收到消息:", message);
    BrowserWindow.getAllWindows().forEach((window) => {
      window.webContents.send("getMessage", message);
    });
    // 排除不需要存储的消息
    if (excludeChatMessage(message)) return;
    // 更新本地message和session
    InsertMessages(message, wsUserParams?.id!);
    // TODO:尝试下线的时候更新本地数据库session
    UpdateOrCreateSession(buildSession(message));
  } catch (e) {
    console.error("❗️解析消息失败:", e);
  }
}

// 发送消息
function sendMessage(message: IMessage) {
  if (!ws || ws.readyState !== WebSocket.OPEN) {
    console.warn("📡 WebSocket 不可用，尝试重连...");
    reconnect();
    return;
  }

  try {
    ws.send(JSON.stringify(message));
    storeLocalMessage(message, MessageStatus.success);
  } catch (err) {
    console.error("❌ 发送消息时发生错误:", err);
    storeLocalMessage(message, MessageStatus.error);
  }
}

// 连接关闭
function onClose() {
  console.warn("🔌 WebSocket 已关闭");
  stopHeartBeat();
  reconnect();
}

// 连接错误
function onError(event: any) {
  console.error("⚠️ WebSocket 出现错误:", event);
  if (ws?.readyState !== WebSocket.OPEN) {
    console.warn("📴 WebSocket 未连接，尝试重连...");
    reconnect();
  }
}

// 重连逻辑
function reconnect() {
  if (lockReconnect || reconnectCount >= reconnectCountMax) {
    if (reconnectCount >= reconnectCountMax) {
      console.warn("🚫 达到最大重连次数，停止重连");
    }
    return;
  }
  lockReconnect = true;
  reconnectCount++;
  console.log(`🔁 正在尝试第 ${reconnectCount} 次重连...`);
  reconnectTimer && clearTimeout(reconnectTimer);
  reconnectTimer = setTimeout(() => {
    lockReconnect = false;
    wsUserParams && createWs(wsUserParams);
  }, reconnectInterval);
}

// 开始心跳
async function startHeartBeat() {
  stopHeartBeat(); // 避免重复
  heartTimer = setInterval(async () => {
    console.log("💓 发送心跳包\n");
    sendMessage({ chatType: ChatType.heartBeat, status: 1 } as IMessage);
  }, heartInterval);
}

// 停止心跳
function stopHeartBeat() {
  if (heartTimer) {
    clearInterval(heartTimer);
    heartTimer = null;
    console.log("💤 停止心跳");
  }
}

// 关闭 WebSocket
function closeWs() {
  stopHeartBeat();
  reconnectTimer && clearTimeout(reconnectTimer);
  reconnectTimer = null;

  if (ws) {
    cleanupWebSocket();
    ws.close();
    ws = null;
  }

  resetState();
  console.log("🔒 WebSocket 已关闭手动连接");
}

// 清除 WebSocket 所有事件监听
function cleanupWebSocket() {
  if (!ws) return;
  ws.removeEventListener("open", onOpen);
  ws.removeEventListener("message", onMessage);
  ws.removeEventListener("close", onClose);
  ws.removeEventListener("error", onError);
}

// 重置状态
function resetState() {
  reconnectCount = 0;
  lockReconnect = false;
  stopHeartBeat();
}

// 排除不需要的chatType
function excludeChatMessage(message: IMessage): boolean {
  switch (message.chatType) {
    case ChatType.friendNotify:
      if (message.messageType === MessageType.requestAdd) {
        UpdateOrCreateSession(buildSession(message));
      }
      return true;
    case ChatType.heartBeat:
      return true;
    case ChatType.group:
    case ChatType.friend:
      return excludeMessageType(message);
    default:
      return false;
  }
}

// 排除不需要的messageType
function excludeMessageType(message: IMessage): boolean {
  switch (message.messageType) {
    case MessageType.videoCall:
    case MessageType.voiceCall:
      // 通话记录类型 不需要排除
      if (message.callStatus != CallStatus.record) return true;
      return false;
    default:
      return false;
  }
}

// 存储消息到本地数据库
function storeLocalMessage(message: IMessage, status: MessageStatus) {
  // 排除不要的消息 比如视频通话 wait agree
  if (excludeChatMessage(message)) return;
  InsertMessages({ ...message, status }, wsUserParams?.id ?? 0);
  getTargetWindow("home")?.webContents.send("updateLocalMessage", message);
}

export { createWs, sendMessage, closeWs };
